#pragma once
#include "Tcpserver.hpp"
#include "Common.hpp"
#include <memory>
#include <iostream>
#include <string>
#include <unordered_map>
#include<sstream>
#include<functional>
#include "Util.hpp"
const std::string gspace = " ";
const std::string hspace = "\r\n";
const std::string glinesep = ": ";
const std::string webroot = "./wwwroot";
const std::string homepage = "index.html";
const std::string VERSION = "HTTP/1.1";
const std::string page_404="Error.html";
class HttpRequst
{
public:
    HttpRequst() : _blank_line(hspace),is_static_file(true)
    {
    }
    std::string serialize()
    {
        return nullptr;
    } // 将请求报文进行序列化
    void PareReqLine(const std::string &str)
    {
      std::stringstream ss(str);
        ss >> _method >> _uri >> _version;
    }
    bool Deserialize(std::string *request)
    {
        std::string str;
        bool res=Util::ReadOneLine(request,&str,hspace);
        if(res==false){
            return false;
        }
        LOG(LogLevel::INFO)<<str;
        PareReqLine(str);
        if(this->_uri=="/"){
            _uri=webroot+_uri+homepage;
        }
        else _uri=webroot+_uri;
        auto pos=_uri.find("?");
        if(pos==std::string::npos){
            return true;
        }
        _args=_uri.substr(pos+1);
        _uri=_uri.substr(0,pos);
        is_static_file=false;
        return true;
    } // 反序列化
    std::string getUri() const { return _uri; }
    std::string getArgs() const { return _args; }
    bool get_is_static_file() const { return is_static_file; }
    ~HttpRequst() {}

private:
    std::string _method;                                   // 请求方法 GET POST PUT DELETE
    std::string _uri;                                      // 请求资源路径 /index.html
    std::string _version;                                  // HTTP版本
    std::unordered_map<std::string, std::string> _headers; // 请求头
    std::string _blank_line;                               // 空行
    std::string _text;   
    std::string _args;                                    //请求参数
    bool is_static_file;
};
class HttpRespone
{
public:
    HttpRespone() : _blank_line(hspace),
                    _version(VERSION) {}
    std::string serialize()
    {
        std::string response;
        response += _version + gspace + std::to_string(_code) + gspace + _desc + hspace;
        std::string header;
        for (auto &kv : _headers)
        {
            header += (kv.first + glinesep + kv.second + hspace);
        }
        response += header;
        response += _blank_line;
        response += _text;
        return response;
    } // 将响应报文进行序列化
    bool Deserialize(std::string &response)
    {
        return true;
    } // 反序列化
    ~HttpRespone() {}
    void Setcode(int code){
        _code=code;
        if(code==200){
            _desc="OK";
        }
        else if(code==404){
            _desc="Not Found";
        }
        else if(code==302){
            _desc="See Other";
        }
        else if(code=301){
            _desc="Moved Permanently";
        }
        else{}
    }
    void SetHeader(const std::string &key, const std::string &value){
        auto iter =_headers.find(key);
        if(iter!=_headers.end())
            return;
        _headers.insert(std::make_pair(key, value));  
    }
    bool MakeResponse(){//制作响应接口
        if(_targetfile=="./wwwroot/favicon.ico"){
            LOG(LogLevel::ERROR)<<"请求favicon.ico"<<_targetfile<<"忽略";
            return false;
        }
        if(_targetfile=="./wwwroot/test"){
            //重定向（临时）
            Setcode(302);
            SetHeader("Location","http://www.baidu.com");
            return true;
        }
        bool res=Util::ReadFileContent(_targetfile,&_text);
        if(res==false){
          Setcode(404);
          _targetfile=webroot+"/"+page_404;
          LOG(LogLevel::ERROR)<<_targetfile<<"文件不存在"<<_targetfile;
          std::string filesize = Util::FileSize(_targetfile); 
          Util::ReadFileContent(_targetfile,&_text);
          SetHeader("Content-Length",filesize);
          std::string filetype = Util::GetFileType(_targetfile);
          SetHeader("Content-Type",filetype);
          return true;
        }
        else{
            Setcode(200);
            std::string filesize = Util::FileSize(_targetfile);
            std::string filetype = Util::GetFileType(_targetfile);
            SetHeader("Cache-Control","no-store, no-cache, must-revalidate, max-age=0");
            SetHeader("Content-Type",filetype);
            SetHeader("Content-Length",filesize);
            // SetHeader("Set-Cookie","username=tgw");
            // SetHeader("Set-Cookie","password=1");
            //vector单独设置cookie

            return true;
        }
    }
void setTargetFile(const std::string &file){
    _targetfile=file;
}
void setText(const std::string &text){
    _text=text;
}
private:
public:
    std::string _version;                                  // HTTP版本
    int _code;                                             // 状态码//404 200
    std::string _desc;                                     // 状态描述//Not Found  OK
    std::unordered_map<std::string, std::string> _headers; // 响应头
    std::string _blank_line;                               // 空行
    std::string _text;                                     // 响应体
    std::string _targetfile;                               //目标资源
    std::vector<std::string> _cookies;                      //cookie
};
using http_func_t= std::function<void(HttpRequst&req,HttpRespone&resp)>;
class Http
{
public:
    Http(uint16_t port) : tcpServer(std::make_unique<TcpServer>(port))
    {
    }
    std::string Decode(const std::string &in)
    {
        
    }
    void handlerRequest(std::shared_ptr<Socket> &socket, NetAddr &client)
    {
        std::string httprequst;
        // while (true)
        // {
            int n = socket->Recv(&httprequst); // tcp是有问题的，tcp是面向字节流的
            std::cout<<"----------------------------"<<std::endl;
            std::cout<<httprequst<<std::endl;
            std::cout<<"----------------------------"<<std::endl;  
            // 1.读取完整报头【空行】
            // 2.对报头进行反序列化,提取有效载荷的长度
            // 3.decode
            // 4.看是否达到有效载荷的长度，提取content-length的长度
            // std::cout<<httprequst<<std::endl;
            // if (n > 0)
            // {
                // std::string res;
                // res=Decode(httprequst);
                // if ( res != "")
                // {
                //     HttpRequst req;
                //     req.Deserialize(&res);//反序列化
                    
                // }
                // else
                // {
                //     continue;
                // }
                if(n>0){
                    HttpRequst req;
                    req.Deserialize(&httprequst);//反序列化
                    HttpRespone response;
                    if(!req.get_is_static_file()){
                        //处理请求参数,不是静态资源
                        // if(_http_funcs[req.getUri()]==_http_funcs.end()){
                        //     //Set(404)
                        // }
                        //else{
                            _http_funcs[req.getUri()](req,response);
                            std::string response_str = response.serialize();
                            socket->Send(response_str);
                        //}
                    }
                    else{
                    response.setTargetFile(req.getUri());
                    bool res=response.MakeResponse();
                    if(res==false){
                        //获取图案
                        
                    }
                    std::string response_str = response.serialize();
                    // std::cout<<"----------------------------"<<std::endl;
                    // std::cout<<response_str<<std::endl;
                    // std::cout<<"----------------------------"<<std::endl;
                    socket->Send(response_str);
                    //std::string filename=req.getUri();//请求的资源
                    //构建响应
                    
                    // HttpRespone response;
                    // response._version = "HTTP/1.1";
                    // response._code = 200;
                    // response._desc = "OK";
                    // LOG(LogLevel::INFO)<<"用户请求filename"<<filename;
                    // bool res=Util::ReadFileContent(filename,&response._text);
                    //     response._headers["Content-Type"]="text/html";
                    //     response._headers["Content-Length"]=std::to_string(response._text.size());
                    //     std::string response_str = response.serialize();
                    //     socket->Send(response_str);
                }
                }

            // else
            // {
            //     break;
            // }
        //}
        //LOG(LogLevel::INFO) << "客户端" << client.stringaddr() << "断开连接";
//         // 假设获取到完整请求，开始处理请求
//         HttpRespone response;
//         response._version = "HTTP/1.1";
//         response._code = 200;
//         response._desc = "OK";
//         // response._headers["Content-Type"]="text/html";
//         // response._headers["Content-Length"]="12";
//         // // response._text="<!DOCTYPE html>\
//             //                 <html>\
//             //                 <head>\
//             //                     <meta charset=\"UTF-8\">\
//             //                     <title>Hello World</title>\
//             //                 </head>\
//             //                 <body>\
//             //                     <h1>Hello, World!</h1>\
//             //                 </body>\
//             //                 </html>";
//         std::string filename = webroot + homepage; // 默认首页
//         if (!Util::ReadFileContent(filename, &response._text))
//         {
//             response._code = 404;
//             response._desc = "Not Found";
//             response._text = "404 Not Found";
//         }
//         std::string httpresponse = response.serialize();
//         socket->Send(httpresponse);
// #endif
    }
    void Start()
    {
        tcpServer->Start([this](std::shared_ptr<Socket> &socket, NetAddr &client)
                         { this->handlerRequest(socket, client); });
    }
    void RegisterHttpFunc(const std::string &method, http_func_t func){
      
        std::string str=webroot+method;//./wwwroot/login
        auto iter=_http_funcs.find(str);
        if(iter!=_http_funcs.end()){
            return;
        }
         _http_funcs[str]=func;
    }
    ~Http() {}

private:
    std::unique_ptr<TcpServer> tcpServer;
    std::unordered_map<std::string, http_func_t> _http_funcs;
};
